package vn.sunnet.backviet01.game.coloa.human.enemy;

import java.util.Random;

import org.anddev.andengine.entity.modifier.MoveModifier;
import org.anddev.andengine.entity.modifier.MoveYModifier;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;

import vn.sunnet.backviet01.game.coloa.constant.Constants;

public class DoThu extends MinisterEnemy {
	private static final long[] durationRun = { 60, 60, 60, 60, 60, 60, 60, 60,
			60, 60 };
	private static final long[] durationAttack = { 150, 50, 50, 50, 50, 50, 50 };
	private static final long[] durationRunaway = { 60, 60, 60, 60, 60, 60, 60,
			60, 60, 60 };
	private Random rand;

	private DoThuStates mState;

	private boolean isDodge = false;
	private boolean isMoveBack = false;
	public boolean isAttacted = false;

	private long countTimeDodge = 0;
	private long countDodge = 0;

	private long countTimeMoveBack = 0;
	private long timeMoveBack = 0;

	private int countShot = 0;

	public boolean isDie = false;
	public boolean isAllowAttack = false;

	private float xBack;
	private float yBack;

	public DoThu(int tiledAttack, float pX, float pY,
			TiledTextureRegion pTiledTextureRegion) {
		super(tiledAttack, pX, pY, pTiledTextureRegion);
		setCurrentTileIndex(0);
		this.name = Constants.DOTHU;
		mState = DoThuStates.RUN;
		isAttack = true;
		isAttacted = false;
		rand = new Random();

		if (pTiledTextureRegion.isFlippedHorizontal())
			pTiledTextureRegion.setFlippedHorizontal(false);

		animate(durationRun, 0, 9, true);
	}

	public void resetInfo() {
		mState = DoThuStates.RUNAWAY;
		isDodge = false;
		isMoveBack = false;
		countTimeDodge = 0;
		countShot = 0;
		countDodge = 0;
		isStun = false;
		timeStun = 0;
		isShot = false;
	}

	public void onManagedUpdate(float pSecondsElapsed) {
		if (isAllowChangeStatus) {

			if (isDie) {
				runaway();
				isDie = false;
				isAllowChangeStatus = false;
			} else if (mState == DoThuStates.MOVE_BACK && !isMoveBack) {
				moveBack();
				isAllowChangeStatus = false;
				countTimeMoveBack = System.currentTimeMillis();
			} else if (mState == DoThuStates.DODGE) {
				dodge();
				isAllowChangeStatus = false;
			} else if (isAllowAttack && !isAttacted) {
				attack();
				if (isStun) {
					resetStun();
				}
				isAllowAttack = false;
				isAllowChangeStatus = false;
			}
			else if (isStun && startStun == 0) {
				setStunAction();
				isAllowChangeStatus = false;
			}
		} else if (mState != DoThuStates.RUNAWAY) {
			if (isMoveBack && this.hitPoints > 0) {
				if (countTimeMoveBack + timeMoveBack < System
						.currentTimeMillis()) {
					run();
					mState = DoThuStates.RUN;
					isMoveBack = false;
					timeMoveBack = 0;
					countTimeMoveBack = 0;
				}
			} else if (isDodge && this.hitPoints > 0) {
				if (countTimeDodge + countDodge < System.currentTimeMillis()) {
					run();
					mState = DoThuStates.RUN;
					isDodge = false;
					countDodge = 0;
					countTimeDodge = 0;
				}
			} else if (isStun && startStun != 0) {
				if (timeStun + startStun < System.currentTimeMillis()) {
					resetStunAction();
				}
			}

			if (mState == DoThuStates.ATTACK
					&& this.getCurrentTileIndex() != 10)
				isAttack = false;

			this.revoverHP();
		}

		super.onManagedUpdate(pSecondsElapsed);
	}

	private void resetStunAction() {
		if (isMoveBack) {
			return;
		}

		isStun = false;
		startStun = 0;
		timeStun = 0;

		switch (mState) {
		case RUN:
			resetAnimation(durationRun);
			handler.setVelocityX(init_velocity);
			break;
		case ATTACK:
			resetAnimation(durationAttack);
			break;

		default:
			break;
		}

	}

	private void setStunAction() {
		startStun = System.currentTimeMillis();
		switch (mState) {
		case RUN:
			resetAnimation(resetDuration(durationRun));
			handler.setVelocityX(init_velocity * 0.75f);
			break;
		case ATTACK:
			resetAnimation(resetDuration(durationAttack));
			break;

		default:
			break;
		}

	}

	private long[] resetDuration(long[] duration) {
		int k = duration.length;
		long[] value = new long[k];

		for (int i = 0; i < k; i++) {
			value[i] = (long)(duration[i] * 4 / 3f);
		}

		return value;
	}

	public void run() {
		handler.setEnabled(true);
		handler.setVelocityX(init_velocity);
		if (mTextureRegionMove.isFlippedHorizontal())
			mTextureRegionMove.setFlippedHorizontal(false);
		animate(durationRun, 0, 9, true);
		mState = DoThuStates.RUN;
		isAttacted = false;
	}

	public boolean isShot(final float pX, final float pY) {
		if (mState == DoThuStates.RUNAWAY)
			return false;

		float x = xContain + getX();
		float y = yContain + getY();

		if ((pX > x && pX < x + widthContain)
				&& (pY > y && pY < y + heightContain) && !isDodge
				&& !isMoveBack) {
			countShot++;
			return true;
		}
		return false;
	}

	public void reduceBlood(float blood) {
		super.reduceBlood(blood);
		if (countShot >= 5 && hitPoints > 0 && !isMoveBack) {
			this.isAllowChangeStatus = true;
			mState = DoThuStates.DODGE;
		}
	}

	private void dodge() {
		stopAnimation();
		handler.setEnabled(false);

		if (isStun)
			resetStun();

		float target = 10 + rand.nextFloat() * (300);
		float y = this.getY();
		float time = Math.abs(y - target) / 300;
		countDodge = (long) (time * 1000);
		System.out.println("target" + "  " + target);
		System.out.println("time" + "  " + time);
		System.out.println("y" + "  " + y);

		MoveYModifier modifier = new MoveYModifier(time, y, target);
		registerEntityModifier(modifier);

		countShot = 0;
		countTimeDodge = System.currentTimeMillis();
		isDodge = true;
		mState = DoThuStates.DODGE;
	}

	protected void createContain() {
		xContain = 50;
		yContain = 40;

		widthContain = 50;
		heightContain = 110;
	}

	private void resetStun() {
		isStun = false;
		timeStun = 0;
		startStun = 0;
	}

	private void moveBack() {
		stopAnimation(10);
		timeMoveBack = 500;
		if (xBack > 750)
			xBack = 750;
		MoveModifier modifier = new MoveModifier(0.5f, this.getX(), xBack,
				this.getY(), yBack);
		this.registerEntityModifier(modifier);

		if (isStun)
			resetStun();

		handler.setEnabled(false);
		status = Constants.MOVE;
		isMoveBack = true;
		isAttacted = true;

	}

	public void moveBack(final float pX, final float pY) {
		if (isDodge || isMoveBack)
			return;
		xBack = pX;
		yBack = pY;
		mState = DoThuStates.MOVE_BACK;
		allowChangeStatus(true);
		isAttacted = false;
	}

	public void attack() {
		handler.setEnabled(false);
		animate(durationAttack, 10, 16, true);
		setCurrentTileIndex(11);
		isAttack = true;
		isAttacted = true;
	}

	public void runaway() {
		isAttacted = false;
		stopAnimation();
		this.setFlippedHorizontal(true);
		if (!handler.isEnabled())
			handler.setEnabled(true);
		animate(durationRunaway, 0, 9, true);
		handler.setVelocityX(Constants.VELOCITY_DOTHU_DEFAULT * 1.5f);
		resetInfo();
	}

	public void updateTextureRegion(TiledTextureRegion pTiledTextureRegion,
			boolean isReset) {
		super.updateTextureRegion(pTiledTextureRegion, isReset);
	}

	public DoThuStates getState() {
		return mState;
	}

	public void setState(DoThuStates pState) {
		mState = pState;
	}
	
	public void setAttackBasic() {
		this.attackBasic = this.intelligent;
	}
	
	public static enum DoThuStates {
		RUN(0), ATTACK(1), RUNAWAY(2), MOVE_BACK(3), DODGE(4);

		int index = -1;

		DoThuStates(int i) {
			index = i;
		}

		public int getIndex() {
			return index;
		}
	}

}
